// /////////////////////////////////////////////////////////////////////////////
//
// Name:            OctTreeComponent.h
// Author:          Michael Bartsch (ZCCdark203)
//
// Desc :           Declaration of the OctTreeComponent class.
//
// License:         Copyright (C) 2009 Michael Bartsch and Contributors
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the zlib/libpng License.
//                  See main.cpp for conditions of distribution and use.
//
// /////////////////////////////////////////////////////////////////////////////

#ifndef __OCTTREECOMPONENT_H__
#define __OCTTREECOMPONENT_H__

// Include files
#include "../../dependencies.h"
#include "MeshComponent.h"


// OctTreeComponent class
//! Component wrapper of Irrlicht's SceneManager function addOctTreeSceneNode(...).
//!
//! <b>XML:</b>
//! \code
//! <OctTreeComponent>
//!    <!-- Properties -->
//! </OctTreeComponent>
//! \endcode
class OctTreeComponent : public MeshComponent
{
public:

    // Initialisation and deinitialisation
    //! Constructor (default)
    //! @param parent        The parent entity to which the component should be added.
    //! @param minPolysPerNode 	Specifies the minimal polygons contained a octree node. If a node
    //!                         gets less polys than this value it will not be split into smaller
    //!                         nodes.
    OctTreeComponent(Entity *parent, s32 minPolysPerNode = 256);
    //! Constructor
    //! @param parent        The parent entity to which the component should be added.
    //! @param fileName      Filename of the mesh to load.
    //! @param minPolysPerNode 	Specifies the minimal polygons contained a octree node. If a node
    //!                         gets less polys than this value it will not be split into smaller
    //!                         nodes.
    OctTreeComponent(Entity *parent, const std::string &fileName, s32 minPolysPerNode = 256);
    //! Constructor
    //! @param parent        The parent entity to which the component should be added.
    //! @param mesh          Pointer to the loaded animated mesh to be displayed.
    //! @param minPolysPerNode 	Specifies the minimal polygons contained a octree node. If a node
    //!                         gets less polys than this value it will not be split into smaller
    //!                         nodes.
    //! @note Not available in AngelScript.
    OctTreeComponent(Entity *parent, IMesh *mesh, s32 minPolysPerNode = 256);
    //! Constructor
    //! @param parent        The parent entity to which the component should be added.
    //! @param mesh          Pointer to the loaded animated mesh to be displayed.
    //! @param minPolysPerNode 	Specifies the minimal polygons contained a octree node. If a node
    //!                         gets less polys than this value it will not be split into smaller
    //!                         nodes.
    //! @note Not available in AngelScript.
    OctTreeComponent(Entity *parent, IAnimatedMesh *mesh, s32 minPolysPerNode = 512);
    //! Deconstructor
    ~OctTreeComponent();

    // Methods
    //! Loads and sets a new mesh to display.
    //! fileName             Filename of the mesh to load.
    void setMesh(const std::string &fileName);
    //! Sets a new mesh to display.
    //! @param mesh          Pointer to the loaded animated mesh to be displayed.
    //! @note Not available in AngelScript.
    void setMesh(IMesh *mesh);

    // Events
    //! Responds to changes of the mesh attached to this component.
    //! @note For internal use only!
    void onMesh(void *p);

    // Serialization
    //! Serializes this object.
    //! @param attributes
    virtual bool onSerialization(SerializedAttributes *attributes);
    //! Deserializes this object.
    //! @param attributes
    virtual bool onDeserialization(SerializedAttributes *attributes);

private:

    // Private methods
    //! Common initialisation method.
    void init(s32 minPolysPerNode);

    // Private members
    ITriangleSelector *mOctTreeSelector;
    IMetaTriangleSelector *mLocalMetaSelector;

    s32 mMinPolysPerNode;
};

#endif
